package com.hjm.common.api.ls.leshua;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hjm.framework.web.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.*;

@Slf4j
@Component
public class LeShuaUtil {
    @Autowired
    private static LeShuaParams leShuaParams;
    private static final List<String> IGNORE_LIST = new ArrayList<>(16);

    static {
        IGNORE_LIST.add("sign");
        IGNORE_LIST.add("source");
        IGNORE_LIST.add("others");
    }
    public static<T> Map<String,Object> commonRemote(T t,String url,String key) {
        try {
            //设置sign
            Method setSignMethod = t.getClass().getMethod("setSign", String.class);
            Object s = setSignMethod.invoke(t,md5ParamByKey(t,key));
            //参数转json
            Method method = t.getClass().getMethod("toJson");
            String jsonStrBody = (String) method.invoke(t);
            if (url.contains("uploadMerchantPic")){
                Map<String,Object> logMap=JSONObject.parseObject(jsonStrBody,Map.class);
                logMap.remove("picData");
                log.info("渠道请求包="+JSONObject.toJSONString(logMap));
            }else {
                log.info("渠道请求包="+jsonStrBody);
            }
            log.info("渠道请求地址="+url);
            JSONObject result = LsShuaHttpUtil.doPost(url, jsonStrBody, null);
            log.info("渠道应答包="+result);

            Map respMap=JSONObject.parseObject(result.toString(),Map.class);
            Map returnMap=new HashMap();
            if((Integer) result.get("error_code") == 0){
                returnMap.put("respData",respMap.get("data"));
                returnMap.put("trace_no",respMap.get("trace_no"));
                returnMap.put("resultCode","0000");
                returnMap.put("resultMsg","成功");
            }else{
                returnMap=resultMap(respMap.get("error_code").toString(),respMap.get("error_msg").toString());
            }
            return returnMap;
        } catch (Exception e) {
            log.error("请求渠道异常：",e);
            return resultMap("0099","系统异常");
        }
    }
    public static<T> AjaxResult commonRemote(T t, String url) {
        try {
            //设置sign
            Method setSignMethod = t.getClass().getMethod("setSign", String.class);
            Object s = setSignMethod.invoke(t,md5ParamByKey(t));
            //参数转json
            Method method = t.getClass().getMethod("toJson");
            String jsonStrBody = (String) method.invoke(t);
            log.info("渠道请求包="+jsonStrBody);
            JSONObject result = LsShuaHttpUtil.doPost(url, jsonStrBody, null);
            log.info("渠道应答包="+result);
            if((Integer) result.get("error_code") == -9999){
                return AjaxResult.error(result.toJSONString());
            }
            if((Integer) result.get("error_code") == 0){
                return AjaxResult.success(result.getJSONArray("data"));
            }else{
              /*  String msgContent = result.getString("tusn");
                int startIndex = msgContent.indexOf("(");
                int endIndex = msgContent.lastIndexOf(")");
                String sn = msgContent.substring(startIndex,endIndex).replaceAll("\\[", "");*/
                return AjaxResult.error(result.get("error_msg").toString());
            }
        } catch (Exception e) {
            log.error("请求渠道异常：",e);
        }
        return AjaxResult.warn("渠道请求失败");
    }

    private static Map resultMap(String resultCode,String resultMsg){
        Map respMap = new HashMap();
        respMap.put("resultCode",resultCode);
        respMap.put("resultMsg",resultMsg);
        return respMap;
    }

    public static String md5ParamByKey(Object obj) {
        JSONObject jsonObject = new JSONObject(16);
        Class<?> objClass = obj.getClass();
        List<Field> fields = getAllField(objClass);
        getParameterJsonObject(jsonObject,fields,obj);
        System.out.println("请求体为---------->:" + jsonObject);
        jsonObject.put("key", "BC2ECF75539743519126B23E0DED5210");
        Set<String> keySet = jsonObject.keySet();
        List<String> keys = new ArrayList<>(keySet);
        Collections.sort(keys);
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            Object value = jsonObject.get(key);
            //value为空跳过  sign跳过  source跳过   others跳过
            if (null == value || IGNORE_LIST.contains(key)) {
                continue;
            }
            if(value instanceof Collection){
                value = JSONObject.toJSONString(value);
            }
            sb.append(key).append("=").append(value).append("&");
        }
        String str = sb.toString();
        String sourceStr = str.substring(0, str.length() - 1);

        System.out.println("签名字符串为---------->:" + sourceStr);

        String backSign = CommonMd5.md5(sourceStr).toUpperCase();

        System.out.println("正确后台sign---------->:" + backSign);

        return backSign;
    }
    public static String md5ParamByKey(Object obj,String signKey) {
        JSONObject jsonObject = new JSONObject(16);
        Class<?> objClass = obj.getClass();
        List<Field> fields = getAllField(objClass);
        getParameterJsonObject(jsonObject,fields,obj);
        System.out.println("请求体为---------->:" + jsonObject);
        jsonObject.put("key", signKey);
        Set<String> keySet = jsonObject.keySet();
        List<String> keys = new ArrayList<>(keySet);
        Collections.sort(keys);
        StringBuilder sb = new StringBuilder();
        for (String key : keys) {
            Object value = jsonObject.get(key);
            //value为空跳过  sign跳过  source跳过   others跳过
            if (null == value || IGNORE_LIST.contains(key)) {
                continue;
            }
            if(value instanceof Collection){
                value = JSONObject.toJSONString(value);
            }
            sb.append(key).append("=").append(value).append("&");
        }
        String str = sb.toString();
        String sourceStr = str.substring(0, str.length() - 1);

        System.out.println("签名字符串为---------->:" + sourceStr);

        String backSign = CommonMd5.md5(sourceStr).toUpperCase();

        System.out.println("正确后台sign---------->:" + backSign);

        return backSign;
    }

    private static List<Field> getAllField(Class clazz) {
        List<Field> fieldList = new ArrayList<>(16);
        while (clazz != null && !StringUtils.equals(clazz.getName().toLowerCase(), "java.lang.Object")) {
            fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        return fieldList;
    }

    public static String parameterToJson(Object obj) {
        JSONObject jsonObject = new JSONObject(16);
        List<Field> allField = getAllField(obj.getClass());
        getParameterJsonObject(jsonObject,allField,obj);
        return jsonObject.toJSONString();
    }

    private static void getParameterJsonObject(JSONObject jsonObject,List<Field> allField,Object obj) {
        for (Field field : allField) {
            field.setAccessible(true);
            try {
                jsonObject.put(field.getName(), field.get(obj));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     ********************************************************* .<br>
     * [方法] changeMoney <br>
     * [描述] 将金额元转换为分 <br>
     * [参数] 金额单位元 <br>
     * [返回] String <br>
     * [时间] 2016-12-21 上午9:53:33 <br>
     ********************************************************* .<br>
     */
    public static String changeMoneyToFen(String amount) throws Exception {
        NumberFormat format = NumberFormat.getInstance();
        Number number = format.parse(amount);
        double temp = number.doubleValue() * 100.0;
        // 默认情况下GroupingUsed属性为true 不设置为false时,输出结果为2,012
        format.setGroupingUsed(false);
        // 设置返回数的小数部分所允许的最大位数
        format.setMaximumFractionDigits(0);
        return format.format(temp);
    }

    /**
     ********************************************************* .<br>
     * [方法] changeMoneyToYuan <br>
     * [描述] 将分转为元 <br>
     * [参数] 金额单位分 <br>
     * [返回] String <br>
     * [时间] 2016-12-29 上午11:22:15 <br>
     ********************************************************* .<br>
     */
    public static BigDecimal changeMoneyToYuan(String amount) {
        return new BigDecimal(amount).setScale(2, BigDecimal.ROUND_DOWN)
                .divide(new BigDecimal(100));
    }

}
